package com.example.videoplayer.controller;

import com.example.videoplayer.model.User;
import com.example.videoplayer.service.AuthService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.security.web.server.context.WebSessionServerSecurityContextRepository;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;

import java.util.Map;

@RestController
@RequestMapping("/api/auth")
public class AuthController {
    private static final Logger logger = LoggerFactory.getLogger(AuthController.class);
    private static final WebSessionServerSecurityContextRepository securityContextRepository = new WebSessionServerSecurityContextRepository();

    @Autowired
    private AuthService authService;

    @PostMapping("/login")
    public Mono<ResponseEntity<User>> login(@RequestBody Map<String, String> credentials, ServerWebExchange exchange) {
        String username = credentials.get("username");
        String password = credentials.get("password");

        if (username == null || password == null) {
            return Mono.just(ResponseEntity.badRequest().build());
        }

        logger.debug("Attempting login for user: {}", username);
        
        return authService.authenticate(username, password)
                .flatMap(user -> {
                    // 创建认证令牌
                    Authentication auth = new UsernamePasswordAuthenticationToken(
                        user, null, user.getAuthorities());
                    
                    // 保存认证上下文到会话
                    return securityContextRepository.save(exchange, new SecurityContextImpl(auth))
                            .then(Mono.just(ResponseEntity.ok(user)));
                })
                .doOnSuccess(response -> {
                    if (response.getStatusCode().is2xxSuccessful()) {
                        logger.info("User logged in successfully: {}", username);
                    }
                })
                .defaultIfEmpty(ResponseEntity.status(401).build())
                .doOnError(e -> logger.error("Login error for user {}: {}", username, e.getMessage()));
    }

    @PostMapping("/logout")
    public Mono<ResponseEntity<Void>> logout(Authentication auth, ServerWebExchange exchange) {
        if (auth != null) {
            String username = auth.getName();
            logger.debug("Logging out user: {}", username);
            return securityContextRepository.save(exchange, null)
                    .then(authService.logout())
                    .then(Mono.fromCallable(() -> {
                        logger.info("User logged out successfully: {}", username);
                        return ResponseEntity.ok().<Void>build();
                    }));
        }
        return Mono.just(ResponseEntity.ok().build());
    }

    @GetMapping("/status")
    public Mono<ResponseEntity<User>> getStatus(Authentication auth) {
        if (auth != null && auth.isAuthenticated()) {
            User user = (User) auth.getPrincipal();
            logger.debug("User status check: {} is authenticated", user.getUsername());
            return Mono.just(ResponseEntity.ok(user));
        }
        logger.debug("User status check: no authenticated user");
        return Mono.just(ResponseEntity.ok().build());
    }
} 